home *** CD-ROM | disk | FTP | other *** search
- /*
- * KeyClick v1.0
- *
- * Adds a clicking sound to each keypress. Yes, it's not the first
- * program of its kind...
- *
- * Martin W. Scott, 22/05/92.
- */
-
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <devices/input.h>
- #include <devices/inputevent.h>
- #include <intuition/intuition.h>
- #include <libraries/gadtools.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/intuition.h>
- #include <proto/gadtools.h>
- #include "beep.h"
- #include "window.h"
-
- #define register /* let optimiser decide */
-
- #define CONFIG_FILE "S:KeyClick.config"
-
- #define TASK_PRIORITY 19 /* always get to beep */
- #define HANDLER_PRIORITY 70 /* avoid (most) manufactured input-events */
-
- typedef struct {
- struct Task *buddy; /* task starting handler */
- ULONG sigmask; /* signal to give parent */
- } GLOBAL_DATA;
-
-
- struct InputEvent __regargs *myhandler(struct InputEvent *, register GLOBAL_DATA *);
-
-
- /*** HANDLER CODE ***/
-
- struct InputEvent __regargs *myhandler(ev,gptr)
- struct InputEvent *ev;
- register GLOBAL_DATA *gptr;
- {
- register struct InputEvent *ep;
-
- for (ep = ev; ep; ep = ep->ie_NextEvent)
- {
- if ((ep->ie_Class == IECLASS_RAWKEY) && !(ep->ie_Code & IECODE_UP_PREFIX))
- Signal(gptr->buddy,gptr->sigmask);
- }
-
- return (ev);
- }
-
-
- /*** GLOBAL DATA STRUCTURES ***/
- struct IntuitionBase *IntuitionBase;
- struct GadToolsBase *GadToolsBase;
- struct MsgPort *inputPort;
- struct IOStdReq *inputRequest;
- struct Interrupt handlerstuff;
- GLOBAL_DATA global;
-
- LONG click_vol = 32; /* initial volume - must be multiple of 2 */
- LONG click_freq = 2300; /* and frequency - must be a multiple of 25 */
- LONG click_on = 1; /* beeping on or off? */
-
- BOOL prefsloaded; /* disk-resident preferences loaded ok? */
-
- void _main(char *); /* prototype for _main */
-
- /*** MAIN PROGRAM ***/
-
- void CloseLibs()
- {
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (GadToolsBase) CloseLibrary(GadToolsBase);
- }
-
- BOOL OpenLibs()
- {
- if ((IntuitionBase = (void *)OpenLibrary("intuition.library",37L)) &&
- (GadToolsBase = (void *)OpenLibrary("gadtools.library",37L)))
- return TRUE;
-
- CloseLibs();
- return FALSE;
- }
-
- #define KCLK 0x4b434c4b
- void LoadConfig()
- {
- ULONG tmp[3];
- BPTR fh;
-
- if (fh = Open(CONFIG_FILE, MODE_OLDFILE))
- {
- if ((Read(fh, tmp, 12) == 12) && tmp[0] == KCLK)
- {
- click_vol = tmp[1];
- click_freq = tmp[2];
- prefsloaded = TRUE;
- }
- Close(fh);
- }
- }
-
- void SaveConfig()
- {
- ULONG tmp[3];
- BPTR fh;
-
- if (fh = Open(CONFIG_FILE, MODE_NEWFILE))
- {
- tmp[0] = KCLK;
- tmp[1] = click_vol;
- tmp[2] = click_freq;
-
- Write(fh, tmp, 12);
- Close(fh);
- }
- }
-
- void _main() /* beep on keypresses */
- {
- WORD sigbit = -1; /* signal for our handler to use */
- LONG oldpri; /* task priority before we change it */
- LONG sigmask; /* signals we're waiting for */
- LONG signals; /* and what we received */
-
-
- /*** Open/allocate libraries, ports, IO requests, signals, Window ***/
-
- LoadConfig(); /* load user-settings */
-
- if ((inputPort = CreateMsgPort()) &&
- (inputRequest = CreateIORequest(inputPort, sizeof(struct IOStdReq))) &&
- ((sigbit = AllocSignal(-1)) != -1) &&
- (AllocAudio() == TRUE) &&
- OpenLibs() &&
- !SetupScreen() &&
- !OpenClickWindow())
- {
- if (prefsloaded) ZipWindow(ClickWnd);
-
- global.buddy = FindTask(NULL); /* initialize liason structure */
- global.sigmask = 1 << sigbit;
- oldpri = SetTaskPri(global.buddy, TASK_PRIORITY);
-
- handlerstuff.is_Data = (APTR)&global; /* set up handler */
- handlerstuff.is_Code = (void *)(myhandler);
- handlerstuff.is_Node.ln_Pri = HANDLER_PRIORITY;
-
- if (!OpenDevice("input.device",0,inputRequest,0))
- {
- inputRequest->io_Command = IND_ADDHANDLER;
- inputRequest->io_Data = (APTR)&handlerstuff;
- DoIO(inputRequest); /* install handler */
-
- sigmask = global.sigmask | (1 << ClickWnd->UserPort->mp_SigBit);
-
- for (;;) /** wait for messages **/
- {
- struct IntuiMessage *msg;
- struct Gadget *gadget;
- struct PropInfo *pi;
- ULONG class;
- UWORD code;
-
- signals = Wait(sigmask);
-
- if (signals & global.sigmask)
- {
- if (click_on)
- {
- beep(click_vol,click_freq);
- Delay(1); /* avoid ugly sound when key repeating */
- }
- }
- if (!(signals ^ global.sigmask)) /* no idcmp */
- continue;
-
- while (msg = GT_GetIMsg(ClickWnd->UserPort))
- {
- class = msg->Class;
- code = msg->Code;
- gadget = (struct Gadget *)msg->IAddress;
- GT_ReplyIMsg(msg);
-
- if (class & SLIDERIDCMP) /* change of settings */
- {
- if (gadget->GadgetID == GD_Vol)
- {
- pi = (struct PropInfo *) ClickGadgets[GDX_Vol]->SpecialInfo;
- click_vol = ((pi->HorizPot+1) * 64) / 0xFFFF;
- beep(click_vol,click_freq);
- }
- else if (gadget->GadgetID == GD_Freq)
- {
- pi = (struct PropInfo *) ClickGadgets[GDX_Freq]->SpecialInfo;
- click_freq = ((pi->HorizPot+1) * 2300) / 0xFFFF + 100;
- beep(click_vol,click_freq);
- }
- }
-
- if (class == GADGETUP) /* could be sliders, but ignore if so */
- {
- if (gadget->GadgetID == GD_Toggle)
- click_on ^= 1;
- else if (gadget->GadgetID == GD_Save)
- SaveConfig();
- }
- else if (class == REFRESHWINDOW)
- {
- GT_RefreshWindow( ClickWnd, NULL );
- }
- else if (class == CLOSEWINDOW)
- goto byebye;
-
- } /* while */
-
- } /* for (;;) */
- byebye:
- inputRequest->io_Command = IND_REMHANDLER;
- inputRequest->io_Data = (APTR)&handlerstuff;
- DoIO(inputRequest); /* remove handler */
- CloseDevice(inputRequest);
- }
- else PutStr("Can't open input.device\n");
-
- SetTaskPri(global.buddy, oldpri); /* restore task's priority */
- }
- else PutStr("Can't alloc resources\n");
-
- /*** Close/free what we opened/allocated ***/
-
- CloseClickWindow();
- CloseDownScreen();
- CloseLibs();
- FreeAudio();
- if (inputRequest) DeleteIORequest(inputRequest);
- if (inputPort) DeleteMsgPort(inputPort);
- if (sigbit != -1) FreeSignal(sigbit);
- }
-